var fc5_utils = {
    customHeader: {
        'X-Requested-By': 'falcon5'
    },
    /**
     * 确保 URL 使用安全的协议
     * 根据当前环境和参数决定是否强制使用 HTTPS
     * 
     * @param {string} url - 原始 URL
     * @param {boolean} [forceHttps=false] - 是否强制使用 HTTPS
     * @returns {string} 处理后的 URL
     */
    ensureSecureUrl: function(url, forceHttps = false) {
        // 如果是相对 URL，直接返回
        if (url.startsWith('/') || url.startsWith('./') || url.startsWith('../')) {
            return url;
        }
        
        // 如果是协议相对 URL (//example.com)，使用当前页面的协议
        // 或者根据 forceHttps 参数决定使用 https
        if (url.startsWith('//')) {
            return (forceHttps ? 'https:' : window.location.protocol) + url;
        }
        
        // 如果是 HTTP URL 且需要强制 HTTPS 或当前页面是 HTTPS，则转换为 HTTPS
        if (url.startsWith('http:') && (forceHttps || window.location.protocol === 'https:')) {
            return url.replace('http:', 'https:');
        }
        
        return url;
    },
    
    /**
     * 获取当前页面的协议（不包含 ://）
     * 与服务器端的 falcon5_get_protocol 函数对应
     * 
     * @returns {string} 当前协议（'http' 或 'https'）
     */
    getProtocol: function() {
        return window.location.protocol === 'https:' ? 'https' : 'http';
    },
    /**
     * Log a message to console with Utils prefix
     * @param {string} message - Message to log
     */
    log: function (message) {
        console.log("Utils Log: " + message);
    },

    /**
     * Get current URI path without language prefix
     * @param {Object} [settings] - Language settings containing format and original language
     * @returns {string} URI path without language code
     */
    get_uri_path: function (settings) {
        // 优先获取 data-original-path 属性
        const originalPath = document.documentElement.getAttribute('data-original-path');
        if (originalPath) {
            return originalPath;
        }

        const uriPath = window.location.pathname;
        const hostname = window.location.hostname;
        
        // 语言代码正则
        const langRegex = /^(?:af|sq|am|ar|hy|az|eu|be|bn|bs|bg|ca|ceb|ny|zh-cn|zh-tw|co|hr|cs|da|nl|en|eo|et|tl|fi|fr|fy|gl|ka|de|el|gu|ht|ha|haw|iw|hi|hmn|hu|is|ig|id|ga|it|ja|jw|kn|kk|km|ko|ku|ky|lo|la|lv|lt|lb|mk|mg|ms|ml|mt|mi|mr|mn|my|ne|no|ps|fa|pl|pt|pa|ro|ru|sm|gd|sr|st|sn|sd|si|sk|sl|so|es|su|sw|sv|tg|ta|te|th|tr|uk|ur|uz|vi|cy|xh|yi|yo|zu)$/i;

        if (settings?.languageFormat === 'sub-domain') {
            // 子域名模式：保持路径不变，只处理子域名
            return uriPath;
        } else {
            // 子目录模式：移除路径中的语言代码
            return uriPath.replace(/^\/(?:af|sq|am|ar|hy|az|eu|be|bn|bs|bg|ca|ceb|ny|zh-cn|zh-tw|co|hr|cs|da|nl|en|eo|et|tl|fi|fr|fy|gl|ka|de|el|gu|ht|ha|haw|iw|hi|hmn|hu|is|ig|id|ga|it|ja|jw|kn|kk|km|ko|ku|ky|lo|la|lv|lt|lb|mk|mg|ms|ml|mt|mi|mr|mn|my|ne|no|ps|fa|pl|pt|pa|ro|ru|sm|gd|sr|st|sn|sd|si|sk|sl|so|es|su|sw|sv|tg|ta|te|th|tr|uk|ur|uz|vi|cy|xh|yi|yo|zu)(?:\/|$)/, '/');
        }
    },

    /**
     * 将对象序列化为 URL 编码的字符串
     * @param {Object} obj - 要序列化的对象
     * @returns {string} URL 编码的字符串
     */
    serialize: function(obj) {
        var str = [];
        for (var p in obj) {
            if (obj.hasOwnProperty(p)) {
                str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
            }
        }
        return str.join("&");
    },

    /**
     * Make a GET request
     * @param {string} url - Request URL
     * @param {Object} [params] - Query parameters
     * @param {Object} [headers] - Request headers
     * @param {Function} [onSuccess] - Success callback
     * @param {Function} [onError] - Error callback
     * @param {boolean} [forceHttps=false] - 是否强制使用 HTTPS
     */
    get: function (url, params, headers, onSuccess, onError, forceHttps = false) {
        if (typeof params === 'function' && typeof headers === 'function') {
            onError = headers;
            onSuccess = params;
            params = {};
        }

        if (typeof headers === 'function') {
            onError = onSuccess;
            onSuccess = headers;
            headers = {};
        }

        if (typeof onSuccess !== 'function') {
            onSuccess = function () {};
        }
        if (typeof onError !== 'function') {
            onError = function () {};
        }

        // 确保 URL 使用安全的协议
        url = fc5_utils.ensureSecureUrl(url, forceHttps);

        const xhr = new XMLHttpRequest();
        xhr.open('GET', url + (params ? '?' + fc5_utils.serialize(params) : ''), true);

        // 设置请求头
        Object.keys(fc5_utils.customHeader).forEach(key => {
            xhr.setRequestHeader(key, fc5_utils.customHeader[key]);
        });
        Object.keys(headers).forEach(key => {
            xhr.setRequestHeader(key, headers[key]);
        });

        xhr.onload = function() {
            if (xhr.status === 200) {
                try {
                    const response = JSON.parse(xhr.responseText);
                    onSuccess(response);
                } catch (e) {
                    onError(new Error('Invalid JSON response'));
                }
            } else {
                onError(new Error(`HTTP error! Status: ${xhr.status}`));
            }
        };

        xhr.onerror = function() {
            onError(new Error('Network error occurred'));
        };

        xhr.send();
    },

    /**
     * Make a POST request with form data
     * @param {string} url - Request URL
     * @param {Object} data - Form data
     * @param {Object} [headers] - Request headers
     * @param {Function} [onSuccess] - Success callback
     * @param {Function} [onError] - Error callback
     * @param {boolean} [forceHttps=false] - 是否强制使用 HTTPS
     */
    post: function (url, data, headers, onSuccess, onError, forceHttps = false) {
        if (typeof data === 'function' && typeof headers === 'function') {
            onError = headers;
            onSuccess = data;
            data = {};
        }

        if (typeof headers === 'function') {
            onError = onSuccess;
            onSuccess = headers;
            headers = {};
        }

        if (typeof onSuccess !== 'function') {
            onSuccess = function () {};
        }

        if (typeof onError !== 'function') {
            onError = function () {};
        }

        // 确保 URL 使用安全的协议
        url = fc5_utils.ensureSecureUrl(url, forceHttps);

        const xhr = new XMLHttpRequest();
        xhr.open('POST', url, true);

        // 设置请求头
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        Object.keys(fc5_utils.customHeader).forEach(key => {
            xhr.setRequestHeader(key, fc5_utils.customHeader[key]);
        });
        Object.keys(headers).forEach(key => {
            xhr.setRequestHeader(key, headers[key]);
        });

        xhr.onload = function() {
            if (xhr.status === 200) {
                try {
                    const response = JSON.parse(xhr.responseText);
                    onSuccess(response);
                } catch (e) {
                    onError(new Error('Invalid JSON response'));
                }
            } else {
                onError(new Error(`HTTP error! Status: ${xhr.status}`));
            }
        };

        xhr.onerror = function() {
            onError(new Error('Network error occurred'));
        };

        xhr.send(fc5_utils.serialize(data));
    },

    /**
     * Make a POST request with JSON data
     * @param {string} url - Request URL
     * @param {Object} data - JSON data
     * @param {Object} [headers] - Request headers
     * @param {Function} [onSuccess] - Success callback
     * @param {Function} [onError] - Error callback
     * @param {boolean} [forceHttps=false] - 是否强制使用 HTTPS
     */
    postJson: function (url, data, headers, onSuccess, onError, forceHttps = false) {
        if (typeof data === 'function' && typeof headers === 'function') {
            onError = headers;
            onSuccess = data;
            data = {};
        }

        if (typeof headers === 'function') {
            onError = onSuccess;
            onSuccess = headers;
            headers = {};
        }

        if (typeof onSuccess !== 'function') {
            onSuccess = function () {};
        }

        if (typeof onError !== 'function') {
            onError = function () {};
        }

        // 确保 URL 使用安全的协议
        url = fc5_utils.ensureSecureUrl(url, forceHttps);

        const xhr = new XMLHttpRequest();
        xhr.open('POST', url, true);

        // 设置请求头
        xhr.setRequestHeader('Content-Type', 'application/json');
        Object.keys(fc5_utils.customHeader).forEach(key => {
            xhr.setRequestHeader(key, fc5_utils.customHeader[key]);
        });
        Object.keys(headers).forEach(key => {
            xhr.setRequestHeader(key, headers[key]);
        });

        xhr.onload = function() {
            if (xhr.status === 200) {
                try {
                    const response = JSON.parse(xhr.responseText);
                    onSuccess(response);
                } catch (e) {
                    onError(new Error('Invalid JSON response'));
                }
            } else {
                onError(new Error(`HTTP error! Status: ${xhr.status}`));
            }
        };

        xhr.onerror = function() {
            onError(new Error('Network error occurred'));
        };

        xhr.send(JSON.stringify(data));
    },

    /**
     * Make a synchronous POST request
     * @param {string} url - Request URL
     * @param {Object} data - Form data
     * @param {Object} [headers] - Request headers
     * @param {boolean} [forceHttps=false] - 是否强制使用 HTTPS
     * @returns {Object} Response data
     * @throws {Error} If request fails
     */
    postSync: function (url, data, headers = {}, forceHttps = false) {
        // 确保 URL 使用安全的协议
        url = fc5_utils.ensureSecureUrl(url, forceHttps);
        
        const xhr = new XMLHttpRequest();
        xhr.open('POST', url, false); // false means synchronous request
        
        // Set default and custom headers
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        for (let key in headers) {
            xhr.setRequestHeader(key, headers[key]);
        }

        // Send request
        xhr.send(fc5_utils.serialize(data));

        // Handle response
        if (xhr.status === 200) {
            try {
                return JSON.parse(xhr.responseText);
            } catch (e) {
                return xhr.responseText;
            }
        }
        
        throw new Error(`Request failed with status ${xhr.status}`);
    },

    /**
     * Show a temporary tip message
     * @param {string} message - Message to show
     * @param {number} [duration=2000] - Duration in milliseconds
     */
    showTip: function(message, duration = 2000) {
        // Remove existing tips
        const existingTips = document.querySelectorAll('.fc5-tip');
        existingTips.forEach(tip => tip.remove());

        // Create new tip
        const tip = document.createElement('div');
        tip.className = 'fc5-tip';
        tip.textContent = message;
        document.body.appendChild(tip);

        // Show tip
        setTimeout(() => tip.classList.add('show'), 10);

        // Remove tip after duration
        setTimeout(() => {
            tip.classList.remove('show');
            setTimeout(() => tip.remove(), 300);
        }, duration);
    },

    /**
     * Show loading mask
     */
    showLoading: function() {
        // Remove existing mask
        this.hideLoading();

        // Create mask
        const mask = document.createElement('div');
        mask.className = 'fc5-loading-mask';
        
        const spinner = document.createElement('div');
        spinner.className = 'fc5-loading-spinner';
        
        mask.appendChild(spinner);
        document.body.appendChild(mask);
    },

    /**
     * Hide loading mask
     */
    hideLoading: function() {
        const existingMask = document.querySelector('.fc5-loading-mask');
        if (existingMask) {
            existingMask.remove();
        }
    }
};